﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using SuperDarts.Gameplay.Modes;
using SuperDarts.ScreenManagement;
using SuperDarts.Screens.Menus;

namespace SuperDarts.Gameplay.Views
{
    public class BaseView : GameScreen
    {
        private const int PlayerPanelMaxWidth = 400;
        private Texture2D _crown;
        public Texture2D DartTexture;
        private float _elapsedTime;
        private Texture2D _glow;
        public float GlowAlpha;
        public GameMode Mode;
        private Texture2D _playerNameBackground;
        private Texture2D _solidDart;
        private const float DartBlinkRate = 500.0f;
        private readonly Texture2D[] _numberTextures = new Texture2D[3];

        public BaseView(GameMode mode)
        {
            Mode = mode;
        }

        public int PlayerCount
        {
            get { return SuperDarts.Players.Count; }
        }

        public virtual void LoadContent(ContentManager content)
        {
            DartTexture = content.Load<Texture2D>(@"Images\DartStroke");
            _solidDart = content.Load<Texture2D>(@"Images\DartHighlight");
            _crown = content.Load<Texture2D>(@"Images\Crown");
            _glow = content.Load<Texture2D>(@"Images\Glow");
            _playerNameBackground = content.Load<Texture2D>(@"Images\PlayerNameBackground");

            for (var i = 0; i < 3; i++)
            {
                _numberTextures[i] =
                    content.Load<Texture2D>(@"Images\" + SuperDarts.Options.Theme + @"\" + @"CricketNumbers\" + (i + 1));
            }
        }

        public override void Update(GameTime gameTime, bool isCoveredByOtherScreen)
        {
            base.Update(gameTime, isCoveredByOtherScreen);

            GlowAlpha = (float) (Math.Sin(gameTime.TotalGameTime.TotalSeconds) + 1.0f)/2.0f;

            _elapsedTime += (float) gameTime.ElapsedGameTime.TotalMilliseconds;
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            base.Draw(spriteBatch);

            spriteBatch.Begin();

            // Temporary variables
            var text = "";
            var position = Vector2.One*20.0f;
            var center = Vector2.Zero;
            Vector2 offset;

            var smallFont = ScreenManager.Trebuchet22;
            var bigFont = ScreenManager.Trebuchet32;
            var scoreFont = ScreenManager.Trebuchet48;

            //Draw game mode name
            text = "Game Mode:";
            TextBlock.DrawShadowed(spriteBatch, smallFont, text, Color.LightBlue, position);
            position.Y += smallFont.LineSpacing;

            text = Mode.Name;
            TextBlock.DrawShadowed(spriteBatch, bigFont, text, Color.White, position);
            position.Y += bigFont.MeasureString(text).Y;

            //Draw round x of y
            text = "Round:";
            TextBlock.DrawShadowed(spriteBatch, smallFont, text, Color.LightBlue, position);
            position.Y += smallFont.LineSpacing;

            text = (Mode.CurrentRoundIndex + 1) + "/" + Mode.MaxRounds;
            TextBlock.DrawShadowed(spriteBatch, bigFont, text, Color.White, position);
            position.Y += bigFont.LineSpacing;

            //Draw current player name
            TextBlock.DrawShadowed(spriteBatch, bigFont, Mode.CurrentPlayer.Name, Mode.CurrentPlayer.Color, position);
            position.Y += bigFont.LineSpacing;

            // Draw player panels
            var playerPanelWidth = SuperDarts.Viewport.Width/SuperDarts.Players.Count;

            if (playerPanelWidth > PlayerPanelMaxWidth)
                playerPanelWidth = PlayerPanelMaxWidth;

            position = new Vector2(SuperDarts.Viewport.Width*0.5f - SuperDarts.Players.Count/2.0f*playerPanelWidth,
                SuperDarts.Viewport.Height*0.8f);
            var leaders = Mode.GetLeaders();
            for (var i = 0; i < PlayerCount; i++)
            {
                text = SuperDarts.Players[i].Name;
                var nameFont = bigFont;
                var nameSize = nameFont.MeasureString(text);

                var background = Color.White*0.33f;
                var foreground = Color.White;
                var shadow = Color.Black;

                var scoreBackground = SuperDarts.Players[i].Color;
                    //SuperDarts.Options.PlayerColors[i % SuperDarts.Options.PlayerColors.Length] * 0.33f;
                var namePanelRectangle = new Rectangle((int) position.X, (int) position.Y, playerPanelWidth,
                    (int) nameSize.Y);

                var score = Mode.GetScore(Mode.Players[i]).ToString();
                var scoreSize = scoreFont.MeasureString(score);

                var y = (int) (position.Y + nameSize.Y);
                var height = SuperDarts.Viewport.Height - y;
                var scoreRectangle = new Rectangle((int) position.X, y, playerPanelWidth, height);

                if (Mode.CurrentPlayerIndex == i)
                {
                    background = Color.White;
                    shadow = Color.White;
                    foreground = SuperDarts.Players[i].Color;

                    //Draw glow
                    spriteBatch.Draw(_glow, new Vector2(scoreRectangle.Center.X, scoreRectangle.Center.Y), null,
                        SuperDarts.Players[i].Color*GlowAlpha, 0, new Vector2(_glow.Width, _glow.Height)*0.5f, 3.0f,
                        SpriteEffects.None, 0);
                }
                else
                {
                    scoreBackground *= 0.33f;
                }

                //Draw player name panel
                spriteBatch.Draw(_playerNameBackground, namePanelRectangle, background);

                //Draw player name
                center = new Vector2(playerPanelWidth, nameSize.Y)*0.5f;
                offset = nameSize*0.5f;
                spriteBatch.DrawString(nameFont, text, position + center - offset + Vector2.One, shadow);
                spriteBatch.DrawString(nameFont, text, position + center - offset, foreground);

                //Draw score background rectangle
                spriteBatch.Draw(ScreenManager.BlankTexture, scoreRectangle, scoreBackground);

                center = new Vector2(playerPanelWidth, height)*0.5f;
                offset = scoreSize*0.5f;

                //Draw score
                var scorePos = new Vector2(position.X, y) + center - offset;
                TextBlock.DrawShadowed(spriteBatch, scoreFont, score, Color.White, scorePos);

                //Draw crown
                if (leaders.Contains(SuperDarts.Players[i]))
                    spriteBatch.Draw(_crown, position + new Vector2(0, nameSize.Y + 10), null, Color.White, 0,
                        Vector2.Zero, 0.5f, SpriteEffects.None, 0);

                position.X += playerPanelWidth;
            }

            // Draw images of darts
            DrawDartScore(spriteBatch);

            spriteBatch.End();
        }

        public virtual void DrawDartScore(SpriteBatch spriteBatch, Vector2 dartSize, Vector2 position, bool vertical)
        {
            Vector2 orientation;

            if (vertical)
                orientation = Vector2.UnitY;
            else
                orientation = Vector2.UnitX;

            var dartTextureSize = new Vector2(DartTexture.Width, DartTexture.Height);
            var temp = position + dartSize*orientation*Mode.CurrentPlayerRound.Darts.Count;

            //Draw images
            for (var i = Mode.CurrentPlayerRound.Darts.Count; i < Mode.DartsPerRound; i++)
            {
                //Blinking dart
                var dartTexturePosition = temp + dartSize*0.5f - dartTextureSize*0.5f;
                if (i == Mode.CurrentPlayerRound.Darts.Count)
                {
                    spriteBatch.Draw(_solidDart, dartTexturePosition,
                        Color.White*(float) (Math.Sin(_elapsedTime*MathHelper.Pi/DartBlinkRate)));
                }

                spriteBatch.Draw(DartTexture, dartTexturePosition, Color.White);
                var numberOffset = new Vector2(_numberTextures[0].Width, _numberTextures[0].Height)*0.5f;

                if (SuperDarts.Options.Debug)
                {
                    numberOffset = ScreenManager.Trebuchet24.MeasureString((i + 1).ToString())*0.5f;
                    spriteBatch.DrawString(ScreenManager.Trebuchet24, (i + 1).ToString(),
                        temp + dartSize*0.5f - numberOffset, Color.White);
                }

                spriteBatch.Draw(_numberTextures[i], temp + dartSize*0.5f - numberOffset, Color.White);

                temp += dartSize*orientation;
            }

            temp = position;
            var center = dartSize*0.5f;

            // Draw dart score
            foreach (var dart in Mode.CurrentPlayerRound.Darts)
            {
                string text;
                Color c;
                dart.GetVerbose(out text, out c);

                var offset = ScreenManager.Trebuchet32.MeasureString(text)*0.5f;
                TextBlock.DrawShadowed(spriteBatch, ScreenManager.Trebuchet32, text, c, temp + center - offset);
                temp += dartSize*orientation;
            }
        }

        public virtual void DrawDartScore(SpriteBatch spriteBatch)
        {
            var dartSize = new Vector2(DartTexture.Width, DartTexture.Height)*1.4f;
            var position = new Vector2(SuperDarts.Viewport.Width*0.5f - Mode.DartsPerRound*0.5f*dartSize.X,
                SuperDarts.Viewport.Height*0.68f);
            DrawDartScore(spriteBatch, dartSize, position, false);
        }

        private Color getColor(Round r)
        {
            var score = Mode.GetScore(r);

            if (score >= 100)
                return Color.Cyan;
            if (score >= 150)
                return Color.Magenta;

            return Color.White;
        }

        /// <summary>
        ///     Draws the score that is displayed for each round to left of the screen
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="position"></param>
        public virtual void DrawRoundScores(SpriteBatch spriteBatch, Vector2 position)
        {
            var text = "";
            var font = ScreenManager.Trebuchet24;

            for (var i = 0; i < Mode.CurrentPlayer.Rounds.Count; i++)
            {
                var r = Mode.CurrentPlayer.Rounds[i];

                var temp = Mode.GetScore(r);
                var c = getColor(r);

                if (i == Mode.CurrentRoundIndex)
                    c = Color.Lerp(Color.LightYellow, Color.Yellow,
                        (float) ((Math.Sin(_elapsedTime*1.0f/500f) + 1.0f)/2.0f));
                else if (i > Mode.CurrentRoundIndex)
                    c = Color.White*0.33f;

                text = "R" + (i + 1) + "." + temp;
                TextBlock.DrawShadowed(spriteBatch, font, text, c, position);
                position.Y += font.LineSpacing*0.8f;
            }
        }
    }
}